package app;

//import org.apache.log4j.BasicConfigurator;
//import org.apache.log4j.Logger;

import geom.*;

import java.util.ArrayList;
import java.util.Iterator;

import org.grlea.log.*;

import app.gui.ProgressBar;

import cluster.Cluster;
import cluster.Duster;

import color.Color;
import color.Rgb;
import processing.core.PApplet;
import processing.core.PFont;
import processing.opengl.*;

public class JColorCluster extends PApplet {
	/**
	 * Logger for this class
	 */
	//private static final Logger logger = Logger.getLogger(JColorCluster.class);

	/**
	 * 
	 */
	
	private static final long serialVersionUID = 1L;
	private final SimpleLogger log = new SimpleLogger(JColorCluster.class);
	ClusterDrawer drawer;
	Cluster<Color> cluster;
	Duster<Color> root;
	
	static public void main(String args[]) {
		//BasicConfigurator.configure();
		PApplet.main(new String[] { 
			//"--present",
			//"--bgcolor=#F00333",
			//"--present-stop-color=#000000",
			"app.JColorCluster" 
		});
	}
	PFont fedra;
	PixelReader reader;
	ProgressBar progress;
	@SuppressWarnings("unchecked")
	public void setup(){
		
		size(1440, 400, OPENGL);
		framerate(10);
		smooth();
		progress = new ProgressBar(0, 100, 1440, 300, new Rgb(240, 150, 20));
		reader = new PixelReader(this, progress);
		String fileName = "autumn";
		ArrayList<Color> colors = Color.getColorArrayFromRgb(
										reader.getColorBins(
											reader.getColors(this, fileName+".jpg"), 300, 12));
//		if (logger.isDebugEnabled()) {
//			logger.debug("setup() - got colors");
//		}
		fedra = this.loadFont("FedraSans-Book-24.vlw");
		
		//ArrayList<Duster<Color>> list = XMLParser.parseInTheMod(this, "rauschenberg1.xml");
		
		try {
//			if (logger.isDebugEnabled()) {
//				logger.debug("setup() - Starting to cluster");
//			}

			cluster = new Cluster<Color>(colors, new float[]{0.4f, 0.1f, 0.03f}, progress);
			//log.debugObject("hey:::", reader.colors);
			//root = cluster.pairClosestCluster(cluster.createDusters();
			
			log.debugObject("hey:::", cluster.root);
			//cluster.mergeDusters(root, 0.5f);
			drawer = new ClusterDrawer(0, 0, this.width, this.height, cluster.root);
			drawer.initTopDown();
			XMLParser.writeXML(this, cluster.root, fileName + ".xml");
			//log.info(Duster.lookup.toString());
		} finally{}
			//catch (InstantiationException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (IllegalAccessException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
	}
	float r = 0;
	public void draw(){
		background(150);
		//directionalLight(80, 80, 80, 0, 0, -1);
		//ambientLight(102, 102, 102);
		progress.draw(this);
		cluster.root.draw(this);
		if(selected != null) drawInfo();
		//if(currentLevel != null)
		//	draw3DLevel();
		
	}
	int level = 0;
	ArrayList<Duster<Color>> currentLevel;
	float size = 500;
	public void draw3DLevel(){

		translate(720, 400, 0);
		r += 0.05;
		rotateY(r);
		Iterator<Duster<Color>> i = currentLevel.iterator();
		
		 while(i.hasNext()){
			 Duster<Color> d = i.next();
			 //Vector pos = Color.getSphericalHsvVector(d.centroid).mult(size);
			 pushMatrix();
			 //translate(pos.getX(), pos.getY(), pos.getZ());
			 float radius = Math.max(d.maxDev * size, 5);
			 
			 noStroke();
			 fill(d.centroid.getRed(), d.centroid.getGrn(), d.centroid.getBlu());
			 emissive(d.centroid.getRed() / 2f, d.centroid.getGrn() / 2f, d.centroid.getBlu() / 2f);
			 ambient(d.centroid.getRed() / 3f, d.centroid.getGrn() / 3f, d.centroid.getBlu() / 3f);
			 sphereDetail(9);
			 sphere(radius);
			 popMatrix();
		 }
		
	}
	int devDiv = 1;
	public void keyPressed(){
		
		if(key == 'a'){
			devDiv++;
			
		}
		if(key == 'z'){
			devDiv--;
			System.out.println("level--");
		}
		if(key == 'a' || key == 'z'){
			setNumGroups();
		}

		
	}
	
	public void setNumGroups(){
		
		try {
			cluster.setMaxDiv(devDiv);
		} catch (Exception e) {
			e.printStackTrace();
		}
		drawer.initTopDown();
	}
	
	Duster<Color> selected = null;
	
	public void drawInfo(){
		int lineHeight = 20;
		int currentHeight = 0;
		int width = 250;
		Color textClr = Color.complementary(selected.centroid);
		if(textClr.getVal() > 0.5f) textClr.setVal(0.15f);
		else textClr.setVal(0.85f);
		translate(mouseX, mouseY - 10 - lineHeight * 4);
		textClr.stroke(this);
		strokeWeight(2);
		fill(selected.centroid.getRed(), selected.centroid.getGrn(), selected.centroid.getBlu());
		rect(0, -lineHeight / 2, width, lineHeight * 8);
		
		textFont(fedra, 12);
		textClr.fill(this);
		text("Color ID" + selected.ID, 5, currentHeight);
		currentHeight += lineHeight;
		text("H: " + selected.centroid.getHue() +
			 "S: " + selected.centroid.getSat() +
			 "V: " + selected.centroid.getVal(), 5, currentHeight);
		currentHeight += lineHeight;
		text("R: " + selected.centroid.getRed() +
			 "G: " + selected.centroid.getGrn() +
			 "B: " + selected.centroid.getBlu(), 5, currentHeight);
		currentHeight += lineHeight;
		text("L: " + selected.centroid.getL() +
			 "a: " + selected.centroid.getA() +
			 "b: " + selected.centroid.getB(), 5, currentHeight);
		currentHeight += lineHeight;
		text("maxDev: " + selected.maxDev + " avgDev: " + selected.avgDev, 5, currentHeight);
		currentHeight += lineHeight;
		text("maxDist: " + selected.maxDist + " minDist: " + selected.minDist, 5, currentHeight);
		currentHeight += lineHeight;
		text("Unique: " + selected.uniqueness, 5, currentHeight);
		currentHeight += lineHeight;
		text("height: " + selected.getHeight() + " height: " + selected.getDepth(), 5, currentHeight);
	}
	
	public void mouseMoved(){
		selected = cluster.root.contains(mouseX, mouseY);
		
	}
	
	public void mouseReleased(){
		Duster<Color> d = cluster.root.contains(mouseX, mouseY);
		if(d == null || d == root) return;
		d.parent.assimilateChild(d);
		cluster.root.sortAll();
		drawer.initTopDown();
	}
	
	public void drawColors(ArrayList<? extends Color> colors){
		
		int baseSize = (int) Math.ceil(Math.sqrt(colors.size() / 2));
		int xSteps = baseSize * 2;
		int ySteps = baseSize;
		float xStep = floor(width / xSteps);
		float yStep = floor(height / ySteps);
		int index = 0;
		for(int y = 0; y < ySteps; y++){
			for(int x = 0; x < xSteps; x++){
				if(index >= colors.size()) return;
				noStroke();
				colors.get(index).fill(this);
				rect(x * xStep + 2, y * yStep + 2, xStep - 4, yStep - 4);
				index++;
			}
		}
	}
	
	
}
